package com.xiaoyi.util;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Base64;

/**
 * 简单的aes加密工具
 */
@SuppressWarnings("all")
public class AesUtil {
    private AesUtil() {
    }

    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";

    private static final String ALGORITHM = "AES";

    private static final String CHARSET = "utf-8";

    private static final String IV = "A-16-Byte-String";

    static {
        // 防止内存中出现多次BouncyCastleProvider的实例
        if (null == Security.getProvider(BouncyCastleProvider.PROVIDER_NAME)) {
            Security.addProvider(new BouncyCastleProvider());
        }
    }

//    private static final String key = "abcxyzqwer123456";

    public static String encrypt(String content, String aesKey) {
        try {
            byte[] decode = content.getBytes(CHARSET);
            byte[] bytes = createKeyAndIv(decode, Cipher.ENCRYPT_MODE, aesKey);
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            throw new RuntimeException("encrypt '" + content + "' exception！", e);
        }
    }


    public static String decrypt(String content, String aesKey) {
        try {
            Base64.Decoder decoder = Base64.getDecoder();
            byte[] decode = decoder.decode(content);
            byte[] bytes = createKeyAndIv(decode, Cipher.DECRYPT_MODE, aesKey);
            return new String(bytes, CHARSET);
        } catch (Exception e) {
            throw new RuntimeException("decrypt '" + content + "' exception！", e);
        }
    }

    private static byte[] createKeyAndIv(byte[] content, int opmode, final String key) throws Exception {
        byte[] keyArray = key.getBytes(CHARSET);
        byte[] iv = IV.getBytes(CHARSET);
        return cipherFilter(content, opmode, keyArray, iv);
    }

    private static byte[] cipherFilter(byte[] content, int opmode, byte[] key, byte[] iv) throws Exception {
        Key secretKeySpec = new SecretKeySpec(key, ALGORITHM);
        AlgorithmParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(opmode, secretKeySpec, ivParameterSpec);
        return cipher.doFinal(content);
    }

}